//
//  HMRefreshControl.swift
//  Weibo
//
//  Created by fuyu on 2017/7/29.
//  Copyright © 2017年 itteacher. All rights reserved.
//

import UIKit

//  自定义下拉刷新控件的高度
let HMRefreshControlHeight: CGFloat = 50

enum HMRefreshControlType {
    //下拉刷新,松手就刷
    case normal
    //松手就刷新
    case pulling
    //正在刷新
    case refreshing
}

//下拉刷新控件
class HMRefreshControl: UIControl {
    //当前下拉刷新控件的状态
    var refreshType: HMRefreshControlType = .normal {
        
        didSet{
            switch refreshType {
            case .normal:
                //  下拉刷新
                //  1. 显示箭头
                iconImageView.isHidden = false
                //  2. 停止风火轮
                indicatorView.stopAnimating()
                //箭头重置
                UIView.animate(withDuration: 0.25, animations: { 
                    self.iconImageView.transform = CGAffineTransform.identity
                }, completion: { (_) in
                    //  oldValue: 表示上一次存储的值
                    if oldValue == .refreshing {
                        //重置停留位置
                        UIView.animate(withDuration: 0.25, animations:{ self.currentScrollView?.contentInset.top -= HMRefreshControlHeight
                        })
                    }

                })
                //文字改成下拉刷新
                messageLabel.text = "下拉刷新"
                
            case .pulling:
                //  松手就刷新
                //  1. 调转箭头
                UIView.animate(withDuration: 0.25, animations: {
                    //  M_PI过期了， 改成3.0用法CGFloat.pi
                    self.iconImageView.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
                })
                //  2. 文字改变成松手就刷新
                messageLabel.text = "松手就刷新"
                
            case .refreshing:
                //  正在刷新
                //  1. 隐藏箭头
                iconImageView.isHidden = true
                //  2. 开启风火轮
                indicatorView.startAnimating()
                //  3. 文字改变成正在刷新
                messageLabel.text = "正在刷新..."
                
                UIView.animate(withDuration: 0.25, animations: {self.currentScrollView!.contentInset.top += HMRefreshControlHeight}, completion: { (_) in
                    //发送刷新事件
                    self.sendActions(for: .valueChanged)
                })
            }
        }
    }
    //记录当前刷新控件的父视图
    var currentScrollView:UIScrollView?
    
    
    //MARK: -- 懒加载控件
    fileprivate lazy var iconImageView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    //刷新内容
    fileprivate lazy var messageLabel: UILabel = {
        
        let label = UILabel()
        label.text = "下拉刷新"
        label.font = UIFont.systemFont(ofSize: 12)
        label.textColor = UIColor.gray
        return label
    }()
    
    //刷新风火轮
    fileprivate lazy var indicatorView: UIActivityIndicatorView = {
        
        let view = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
        return view
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //添加控件和约束
    private func setupUI() {
        
        backgroundColor = UIColor.red

        addSubview(iconImageView)
        addSubview(messageLabel)
        addSubview(indicatorView)
        //代码自动布局
        iconImageView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        
        //设置约束
        addConstraint(NSLayoutConstraint(item: iconImageView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: iconImageView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: -35))
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .centerY, relatedBy: .equal, toItem: iconImageView, attribute: .centerY, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .leading, relatedBy: .equal, toItem: iconImageView, attribute: .trailing, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerY, relatedBy: .equal, toItem: iconImageView, attribute: .centerY, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerX, relatedBy: .equal, toItem: iconImageView, attribute: .centerX, multiplier: 1, constant: 0))

    }
    
    //  将要添加到父视图上
    override func willMove(toSuperview newSuperview: UIView?) {
        //  获取父视图
        print(newSuperview)
        
        guard let scrollView = newSuperview as? UIScrollView else {
            //  表示不是滚动视图，不需要监听其滚动
            return
        }
        //  设置frame
        self.frame = CGRect(x: 0, y: 0 - HMRefreshControlHeight, width: scrollView.frame.size.width, height: HMRefreshControlHeight)
        //  使用kvo监听tableView的滚动
        scrollView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
        //  记录当前滚动视图
        currentScrollView = scrollView
    }
    
    //  kvo监听的方法
    /*
     keyPath: 监听对象的属性
     object: 监听的视图（对象）
     change: 对象改变的信息
     context: 上下文参数
     */
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        let contentOffSetY = currentScrollView!.contentOffset.y
        print(contentOffSetY)
        //  细分来说可以刷新状态可以分为拖动和松手
        //  拖动情况下只有两种状态 normal和pulling之间相互切换
        //  松手情况下，想要进入正在刷新状态，那么前提是当前状态（pulling）才能进入refreshing(正在刷新)
        if currentScrollView!.isDragging {
            //  拖动临近点, contentInset.top ： 内容显示的位置距离顶部的距离
            let limitMaxY = -(currentScrollView!.contentInset.top + HMRefreshControlHeight)
            
            if contentOffSetY < limitMaxY && refreshType == .normal {
                //  进入松手就刷新
                refreshType = .pulling
                print("pulling")
            } else if refreshType == .pulling && contentOffSetY >= limitMaxY {
                //  进入下拉刷新
                refreshType = .normal
                print("normal")
            }
            
            
        } else {
            if refreshType == .pulling {
                //  1. 松手， 2.当前状态是pulling才能进入refreshing
                refreshType = .refreshing
                print("refreshing")
            }
        }
        
        
    }
    //  结束刷新
    func endRefreshing() {
        //  把刷新状态改成默认状态
        refreshType = .normal
    }
    
    //  析构函数
    deinit {
        //  移除kvo
        currentScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }


}
